package com.zsp.comic.service.impl;

import com.zsp.comic.dao.ComicDao;
import com.zsp.comic.dao.MagnetDao;
import com.zsp.comic.dao.VideoDao;
import com.zsp.comic.entity.Comic;
import com.zsp.comic.entity.Magnet;
import com.zsp.comic.entity.Video;
import com.zsp.comic.service.ComicService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author gan
 * @create 2020-12-03 16:56
 */
@Service
public class ComicServiceImpl implements ComicService {
    @Resource
    private ComicDao comicDao;

    @Resource
    private VideoDao videoDao;

    @Resource
    private MagnetDao magnetDao;

    //将视频和磁力链接分别插入
    private void getOneComicDetail(Comic comic){
        if (comic != null){
            List<Video> videos = videoDao.getVideoByComicId(comic.getId());

            //如果视频集不为空则通过播放地址筛选插入视频分组集合
            if (videos != null){
                List<String> addressGroup = videoDao.getVideoAddressGroupByComicId(comic.getId());
                //创建播放地址的视频链接地址集合的map
                Map<String, List<Video>> videoMap = new TreeMap<>();
                for (String group:addressGroup){
                    //创建list集合，用于保存经过播放地址筛选后的视频链接
                    List<Video> childVideos = new ArrayList<>();
                    for(Video video : videos ){
                        if (group.equals(video.getAddress())){
                            childVideos.add(video);
                        }
                    }

                    if (childVideos != null){
                        videoMap.put(group, childVideos);
                    }

                }

                if (videoMap != null){
                    comic.setVideoMap(videoMap);
                }
            }

            List<Magnet> magnets = magnetDao.getMagnetByComicId(comic.getId());
            //如果磁力集不为空则通过字幕组筛选插入字幕组分组集合
            if (magnets != null){
                //创建当前动漫所有字幕组的集合
                List<String> letterGroup = magnetDao.magnetLetterGroupByComicId(comic.getId());
                Map<String, List<Magnet>> magnetMap = new TreeMap<>();
                for (String letter : letterGroup){
                    List<Magnet> childMagnets = new ArrayList<>();
                    for (Magnet magnet : magnets){

                        if (magnet.getLetter() != null && letter != null && magnet.getLetter().equals(letter)){
                            childMagnets.add(magnet);
                        }

                        if (magnet.getLetter() == null && letter == null){
                            childMagnets.add(magnet);
                        }
                    }

                    //字幕组可以为空，为空时就是生肉或者未知字幕组了
                    if (letter == null){
                        magnetMap.put("生肉/不明字幕组", childMagnets);
                    }else {
                        magnetMap.put(letter, childMagnets);
                    }

                }

                if (magnetMap != null){
                    comic.setMagnetMap(magnetMap);
                }
            }
        }
    }

    private void getManyComicDetail(List<Comic> comics){
        if (comics != null){
            for (Comic comic:comics){
                getOneComicDetail(comic);
            }
        }
    }

    @Cacheable(value = "userComicCache", key = "'getAllComic'")
    @Override
    public List<Comic> getAllComic() {
        return comicDao.getAllComic();
    }

    @CachePut(value = "adminComicCache", key = "'getAllComicWithAdminAuthority'")
    @Override
    public List<Comic> getAllComicWithAdminAuthority() {
        return comicDao.getAllComicWithAdminAuthority();
    }

    @CachePut(value = "userComicCache", key = "'getComicByUserId'+#userId")
    @Override
    public List<Comic> getComicByUserId(Integer userId) {
        return comicDao.getComicByUserId(userId);
    }

    //去除查询条件的所有重复条件
    private List<String> removeRepeat(List<String> tags){

        if (tags != null){
            Set set = new HashSet();
            List newTags = new ArrayList();
            for (String cd:tags) {
                if(set.add(cd)){
                    newTags.add(cd);
                }
            }

            return newTags;
        }

        return null;
    }

    //去除当前从数据库查出来标签的null值（比如地区条件：areas）
    private void removeNull(String tagName, List<Map<String, List<String>>> conditionList, List<String> tags){
        if (tags != null){
            Map<String,List<String>> tagMap = new HashMap<>();

            //这个一行用做去除tags中的null值
            tags.removeAll(Collections.singleton(null));

            tagMap.put(tagName,removeRepeat(tags));

            conditionList.add(tagMap);
        }
    }

    //获取所有筛选条件（目录页使用）
    @Cacheable(value = "userComicCache", key = "'getAllCondition'")
    @Override
    public List<Map<String,List<String>>> getAllCondition() {
        List<String> areas = comicDao.getAllArea();
        List<String> types = comicDao.getAllType();
        List<String> premiereTime = comicDao.getAllPremiereTime();
        List<String> status = comicDao.getAllStatus();
        List<String> plotTypes = comicDao.getAllPlotType();

        List<Map<String,List<String>>> condition = new ArrayList<>();

//        这一行一块代码抽取放到removeNull()方法中，使得代码不那么臃肿
//        if (areas != null){
//            Map<String,List<String>> areaMap = new HashMap<>();
//            areas.removeAll(Collections.singleton(null));
//
//            areaMap.put("地区",removeRepeat(areas));
//
//            condition.add(areaMap);
//        }

        removeNull("地区",condition,areas);

//        if (types != null){
//            Map<String,List<String>> typeMap = new HashMap<>();
//            types.removeAll(Collections.singleton(null));
//
//            typeMap.put("动画种类",removeRepeat(types));
//
//            condition.add(typeMap);
//        }

        removeNull("动画种类",condition,types);

        if (premiereTime != null){
            Map<String,List<String>> premiereTimeMap = new HashMap<>();
            List<String> years = new ArrayList<>();
            premiereTime.removeAll(Collections.singleton(null));
            for (String time : premiereTime){
                if (time != null){
                    String[] year = time.split("-");
                    years.add(year[0]);
                }
            }

            premiereTimeMap.put("时间",removeRepeat(years));

            condition.add(premiereTimeMap);
        }

//        if (status != null){
//            Map<String,List<String>> statusMap = new HashMap<>();
//            status.removeAll(Collections.singleton(null));
//
//            statusMap.put("状态",removeRepeat(status));
//
//            condition.add(statusMap);
//        }

        removeNull("状态",condition,status);

        if (plotTypes != null){
            Map<String,List<String>> plotTypeMap = new HashMap<>();
            List<String> pts = new ArrayList<>();

            for (String plotType : plotTypes){
                if (plotType != null){
                    String[] pt = plotType.split(" ");
                    for (int i = 0; i < pt.length; i++) {
                        pts.add(pt[i]);
                    }
                }

            }

            pts.removeAll(Collections.singleton(null));

            plotTypeMap.put("剧情类型",removeRepeat(pts));

            condition.add(plotTypeMap);
        }

        return condition;
    }

    /**
     * @Cacheable 提供两个参数来指定缓存名：value、cacheNames，二者选其一即可
     * value ：缓存的名称，在 spring 配置文件中定义，必须指定至少一个
     * key ： 缓存的 key，可以为空
     */
//    @Cacheable(value = "userComicCache", key = "'getComicById_id_'+#id")
    @Override
    public Comic getComicById(Integer id) {
        Comic comic = comicDao.getComicById(id);
        getOneComicDetail(comic);
        return comic;
    }

    @Cacheable(value = "adminComicCache", key = "'getComicByIdWithAdminAuthority_id_'+#id")
    @Override
    public Comic getComicByIdWithAdminAuthority(Integer id) {
        Comic comic = comicDao.getComicByIdWithAdminAuthority(id);
        getOneComicDetail(comic);
        return comic;
    }

    @CachePut(value = "userComicCache", key = "'getComicByName_name_'+#name")
    @Override
    public List<Comic> getComicByName(String name) {
        List<Comic> comics = comicDao.getComicByName(name);
        getManyComicDetail(comics);
        return comics;
    }

    @CachePut(value = "adminComicCache", key = "'getComicByNameWithAdminAuthority_name_'+#name")
    @Override
    public List<Comic> getComicByNameWithAdminAuthority(String name) {
        List<Comic> comics = comicDao.getComicByNameWithAdminAuthority(name);
        getManyComicDetail(comics);
        return comics;
    }

    @Override
    public Comic getOneComicByNameWithAdminAuthority(String name) {
        if (null != null){
            return comicDao.getOneComicByNameWithAdminAuthority(name);
        }
        return null;
    }

    //@CachePut表示缓存新添加的数据或者更新的数据到缓存中(暂时不知道如何使用缓存操作不定条件查询)
//    @CachePut(value = "userComicCache", key = "'memoryAddress_'+#comic.getMemoryAddress()")
    @CachePut(value = "userComicCache", key = "'getComicByCondition'")
    @Override
    public List<Comic> getComicByCondition(Comic comic) {
        List<Comic> comics = comicDao.getComicByCondition(comic);
        //getManyComicDetail(comics);
        return comics;
    }

    @Cacheable(value = "userComicCache", key = "'serialComic'")
    @Override
    public List<Comic> serialComic() {
        List<Comic> comics = comicDao.serialComic();
        //getManyComicDetail(comics);
        return comics;
    }

    @Cacheable(value = "userComicCache", key = "'indexSerialComic_num_'")
    @Override
    public List<Comic> indexSerialComic(Integer num) {
        List<Comic> comics = comicDao.indexSerialComic(num);
        //getManyComicDetail(comics);
        return comics;
    }

    @Cacheable(value = "userComicCache", key = "'recommendComic'")
    @Override
    public List<Comic> recommendComic() {
        List<Comic> comics = comicDao.recommendComic();
        //getManyComicDetail(comics);
        return comics;
    }

    @Cacheable(value = "userComicCache", key = "'indexRecommendComic'")
    @Override
    public List<Comic> indexRecommendComic(Integer num) {
        List<Comic> comics = comicDao.indexRecommendComic(num);
        //getManyComicDetail(comics);
        return comics;
    }

    //添加动漫
//    @CachePut(value = "adminComicCache", key = "'addComic_memoryAddress'")
    @Override
    public boolean addComic(Comic comic) {
        Integer isAddComic = comicDao.addComic(comic);
        if (isAddComic > 0){
            Comic addComic = comicDao.getOneComicByNameWithAdminAuthority(comic.getName());
            Integer addComicId = addComic.getId();
            String addComicName = addComic.getName();

            Map<String, List<Video>> addComicVideoMap = comic.getVideoMap();
            if (null != addComicId){
                if (null != addComicVideoMap){
                    for (String key : addComicVideoMap.keySet()){
                        List<Video> videos = addComicVideoMap.get(key);
                        for (Video video : videos){
                            video.setName(addComicName);
                            video.setAddress(key);
                            video.setComicId(addComicId);
                        }
                        videoDao.addManyVideo(videos);
                    }
                }

                Map<String, List<Magnet>> addComicMagnetMap = comic.getMagnetMap();
                if (null != addComicMagnetMap){
                    for (String key : addComicMagnetMap.keySet()){
                        List<Magnet> magnets = addComicMagnetMap.get(key);
                        for (Magnet magnet : magnets){
                            magnet.setName(addComicName);
                            magnet.setLetter(key);
                            magnet.setComicId(addComicId);
                        }
                        magnetDao.addManyMagnet(magnets);
                    }
                }
            }
            return true;
        }

        return false;
    }

    //更新动漫
//    @CachePut(value = "adminComicCache", key = "'updateComic_id'")
    @Override
    public boolean updateComic(Comic comic) {
        Integer isUpdateComic = comicDao.updateComic(comic);

        if (isUpdateComic > 0){
            String newComicName = comic.getName();
            Comic newComic = comicDao.getOneComicByNameWithAdminAuthority(newComicName);
            Integer newComicId = newComic.getId();
            Map<String, List<Video>> videoMap = comic.getVideoMap();
            Map<String, List<Magnet>> magnetMap = comic.getMagnetMap();

            List<Video> oldVideos = videoDao.getVideoByComicId(newComicId);
            List<Magnet> oldMagnets = magnetDao.getMagnetByComicId(newComicId);

            if (null != videoMap){
                for (String key : videoMap.keySet()){
                    List<Video> newVideos = videoMap.get(key);
                    if (null != newVideos && null != oldVideos){
                        for (Video newVideo : newVideos){
                            Integer newVideoId = newVideo.getId();
                            for (Video oldVideo : oldVideos){
                                //如果video已经存在，则只要添加更新播放地址和番名就好了
                                if (newVideoId.toString().equals(oldVideo.getId().toString())){
                                    newVideo.setName(newComicName);
                                }
                                //如果video不存在,即newVideoId为空，那么直接添加到video表
                                if (null == newVideoId){
                                    newVideo.setName(newComicName);
                                    newVideo.setComicId(newComicId);
                                    videoDao.addVideo(newVideo);
                                }
                            }
                        }
                        videoDao.updateManyVideo(newVideos);
                    }
                    //如果视频表中原来为空，则直接添加到视频表
                    if (null != newVideos && null == oldVideos){
                        videoDao.addManyVideo(newVideos);
                    }
                }
            }

            if (null != magnetMap){
                for (String key : magnetMap.keySet()){
                    List<Magnet> newMagnets = magnetMap.get(key);
                    if (null != newMagnets && null != oldMagnets){
                        for (Magnet newMagnet : newMagnets){
                            Integer newMagnetId = newMagnet.getId();
                            for (Magnet oldMagnet : oldMagnets){
                                if (newMagnetId.toString().equals(oldMagnet.getId().toString())){
                                    newMagnet.setName(newComicName);
                                }

                                if (null == newMagnetId){
                                    newMagnet.setComicId(newComicId);
                                    newMagnet.setName(newComicName);
                                    magnetDao.addMagnet(newMagnet);
                                }
                            }
                        }
                        magnetDao.updateManyMagnet(newMagnets);
                    }

                    //如果磁力链接表中不存在该番的磁力链接且提交的数据不为空，则直接将提交的磁力链接数据添加到磁力链接表中
                    if (null != newMagnets && null == oldMagnets){
                        magnetDao.addManyMagnet(newMagnets);
                    }
                }
            }
            return true;
        }
        return false;
    }

    //删除动漫
//    @CacheEvict(value = "adminComicCache", key = "'deleteComic_id_'+#id")
    @Override
    public boolean deleteComic(Integer id) {

        if (null != id){
            if (comicDao.deleteComic(id) > 0){
                videoDao.deleteVideoByComicId(id);
                magnetDao.deleteMagnetByComicId(id);
                return true;
            }
        }
        return false;
    }
}
